package com.cuvretool.model;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import com.cuvretool.Model;
import com.cuvretool.bezier.Bezier;
import com.cuvretool.model.detail.DrawString;
import com.cuvretool.model.detail.ModelGroup;
import com.cuvretool.model.detail.ModelUnit;
import com.cuvretool.utils.Vector2;
import com.cuvretool.view.draw.DisplayDraw;
/**
 * N介Bezier曲线计算
 * since 2015年4月21日 上午12:16:33
 * @author boy
 */
public class BezierCurve extends Model {
	// ===========================================================
	// Constants
	// ===========================================================

	// ===========================================================
	// Fields
	// ===========================================================
	/**bezier曲线计算方法*/
	private Bezier mBezier;
	/**计算bezier控制点的点集*/
	private ArrayList<Vector2> mPostions;
	/**边框偏移距离值*/
	private Vector2 mFrameOffset;
	/**被鼠标左键按住标记的点*/
	private Vector2 mMarkPoint;
	/**被标记点信息*/
	private ModelUnit mMarkUnit;
	/**被点击中标记的点*/
	private Vector2 mClickPoint;
	/**鼠标移动到的标记点*/
	private Vector2 mMoveString;
	/**一个组*/
	private ModelGroup mModelGroup;
	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
	@Override
	public void init() {
		super.init();
		mBezier = new Bezier();
		mPostions = new ArrayList<Vector2>();
		mModelGroup = new ModelGroup();
		mModelGroup.mName = "BezierCurve";
		mGroups.add(mModelGroup);
	}
	/**
	 * 更新曲线
	 */
	@Override
	public void run() {
		super.run();
		mBezier.setPostions(mPostions);
		mBezier.run();
		mResulte.clear();
		mResulte.addAll(mBezier.getResulte());
	}
	
	@Override
	public void over() {
		super.over();
		mBezier.over();
		mPostions.clear();
		mPostions = null;
	}
	
	@Override
	public boolean isClickPoint(Vector2 pos) {
		mClickPoint = findHitTarget(pos);
		if(mClickPoint == null){
			return false;
		} else {
			return true;
		}
	}

	@Override
	public boolean isIncreaseOk(Vector2 pos) {
		mPostions.add(pos);
		ModelUnit unit =new ModelUnit();
		unit.mName = "点"+mPostions.size()+": ";
		unit.mPosition = pos;
		mModelGroup.mGroup.add(unit);
		updateOperateTree();
		return true;
	}

	@Override
	public boolean isPressed(int button,Vector2 pos) {
		if(button == MouseEvent.BUTTON1){
			mMarkPoint = findHitTarget(pos);
			if(mMarkPoint != null){
				return true;
			}
		} else if (button == MouseEvent.BUTTON3) {
		}
		return false;
	}
	
	@Override
	public boolean isDragPoint(Vector2 pos) {
		if(mMarkPoint != null){
			mMarkPoint.set(pos);
			mMarkUnit.isChange = true;
			updateOperateTree();
			return true;
		} else {
			return false;
		}
	}
	
	@Override
	public void isReleased(int button) {
		if(button == MouseEvent.BUTTON1){
			mMarkPoint = null;
			mMarkUnit = null;
		} else if (button == MouseEvent.BUTTON3) {
		}
	}
	
	@Override
	public boolean isMove(Vector2 pos) {
		mMoveString = findHitTarget(pos);
		return true;
	}
	
	@Override
	public boolean isKeyPressed(KeyEvent e) {
		boolean is = false;
		int code = e.getKeyCode();
		if(code == KeyEvent.VK_DELETE){
			if(mClickPoint != null){
				mPostions.remove(mClickPoint);
				mMarkUnit.isDelete = true;
				mClickPoint = null;
				ArrayList<ModelUnit> units = mModelGroup.mGroup;
				for (int i = 0; i < units.size(); i++) {
					ModelUnit unit = units.get(i);
					int index = mPostions.indexOf(unit.mPosition);
					unit.mName = "点"+(index+1)+": ";
					unit.isChange = true;
				}
				is = true;
				updateOperateTree();
			}
		}
		return is;
	}
	
	@Override
	public boolean isKeyReleased(KeyEvent e) {
		return super.isKeyReleased(e);
	}
	
	@Override
	public ArrayList<DrawString> getDrawStrings() {
		ArrayList<DrawString> result = null;
		if(mMoveString != null){
			result = new ArrayList<DrawString>();
			DrawString temp = new DrawString();
			temp.mString = mMoveString.toString();
			temp.mPosition = new Vector2(mMoveString);
			temp.mPosition.add(mFrameOffset.x*2, -mFrameOffset.y);
			result.add(temp);
			mMoveString = null;
		}
		return result;
	}
	
	@Override
	public ArrayList<Vector2> getDrawPoints() {
		return mResulte;
	}
	
	@Override
	public ArrayList<ArrayList<Vector2>> getDrawLines() {
		ArrayList<ArrayList<Vector2>> vec = new ArrayList<ArrayList<Vector2>>();
		vec.add(mPostions);
		return vec;
	}
	
	@Override
	public ArrayList<ArrayList<Vector2>> getDrawPolygons() {
		ArrayList<ArrayList<Vector2>> result = new ArrayList<ArrayList<Vector2>> ();
		DisplayDraw displayDraw = DisplayDraw.obtain();
		mFrameOffset = displayDraw.TransformDisplayToDrawLen(new Vector2(5, 5));
		for (int i = 0; i < mPostions.size(); i++) {
			ArrayList<Vector2> temp = new ArrayList<Vector2>();
			Vector2 point = mPostions.get(i);
			temp.add(new Vector2(point.x-mFrameOffset.x,point.y-mFrameOffset.y));
			temp.add(new Vector2(point.x-mFrameOffset.x,point.y+mFrameOffset.y));
			temp.add(new Vector2(point.x+mFrameOffset.x,point.y+mFrameOffset.y));
			temp.add(new Vector2(point.x+mFrameOffset.x,point.y-mFrameOffset.y));
			temp.add(new Vector2(point.x-mFrameOffset.x,point.y-mFrameOffset.y));
			result.add(temp);
		}
		return result;
	}
	// ===========================================================
	// Methods
	// ===========================================================
	/**
	 * 查找是否是否点击中有效目标
	 * @param pos
	 * @return		null未点击中，否则返回目标句柄
	 */
	private Vector2 findHitTarget(Vector2 pos){
		Vector2 result = null;
		for (int i = 0; i < mPostions.size(); i++) {
			result = mPostions.get(i);
			if(pos.x > result.x - mFrameOffset.x && pos.x < result.x + mFrameOffset.x){
				if(pos.y > result.y - mFrameOffset.y && pos.y < result.y + mFrameOffset.y){
					mMarkUnit = mModelGroup.mGroup.get(i);
					break;
				}
			}
			result = null;
		}
		return result;
	}
	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}
